using System;
using System.Net;
using System.Runtime.Serialization;
using System.Security.Permissions;

namespace CloudStorage.API.Exceptions
{
	/// <summary>
	/// An exception to use when Cloud Storage Fails for any reason
	/// </summary>
	[Serializable]
	public class CloudStorageException : Exception
	{
		/// <summary>
		/// Ctor
		/// </summary>
		public CloudStorageException()
		{ }

		/// <summary>
		/// Ctor
		/// </summary>
		public CloudStorageException(string message) : 
			base(message) 
		{ }

		/// <summary>
		/// Ctor
		/// </summary>
		public CloudStorageException(string message, Exception innerException)
			: base(message, innerException)
		{ }

		/// <summary>
		/// Ctor
		/// </summary>
		public CloudStorageException(string message,
																 HttpStatusCode statusCode)
			: base(message, null)
		{
			HttpStatusCode = statusCode;
		}

		/// <summary>
		/// Ctor
		/// </summary>
		public CloudStorageException(string message,
																 HttpStatusCode statusCode,
																 Exception innerException)
			: base(message, innerException)
		{
			HttpStatusCode = statusCode;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="CloudStorageException"/> class with
		/// serialized data.
		/// </summary>
		/// <param name="info">The <see cref="SerializationInfo"/> object that contains serialized object
		/// data about the exception being thrown</param>
		/// <param name="context">The <see cref="StreamingContext"/> object that contains contextual information
		/// about the source or destionation. </param>
		protected CloudStorageException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			HttpStatusCode = (HttpStatusCode)info.GetValue("HttpStatusCode", typeof(HttpStatusCode));
		}

		/// <summary>
		/// The Http status code returned by the storage service
		/// </summary>
		public HttpStatusCode HttpStatusCode { get; private set; }

		/// <summary>
		/// Sets the <see cref="SerializationInfo"/> object with additional exception information
		/// </summary>
		/// <param name="info">The <see cref="SerializationInfo"/> object that holds the 
		/// serialized object data.</param>
		/// <param name="context">The <see cref="StreamingContext"/> object that contains contextual information
		/// about the source or destionation. </param>
		[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			if (null == info)
			{
				throw new ArgumentNullException("info");
			}

			info.AddValue("HttpStatusCode", HttpStatusCode);
			base.GetObjectData(info, context);
		}
	}
}